﻿namespace USElections.Map.Pages
{
    using System;
    using System.Device.Location;
    using System.Diagnostics;
    using System.Linq;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Navigation;
    using AgFx;
    using Microsoft.Phone.Controls;
    using Microsoft.Phone.Shell;
    using Microsoft.Phone.Tasks;
    using Telerik.Windows.Controls;
    using USElections.Map.Classes;
    using USElections.Model;
    using USElections.Utils;

    /// <summary>
    /// MapPage class.
    /// </summary>
    public partial class MapPage : PhoneApplicationPage
    {
        #region Fields
        #endregion

        #region Constructor
        /// <summary>
        /// Initializes a new instance of the MapPage class.
        /// </summary>
        public MapPage()
        {
            InitializeComponent();
        }
        #endregion

        #region Public methods
        /// <summary>
        /// On Navigated to method.
        /// </summary>
        /// <param name="e">The NavigationEventArgs object.</param>
        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            bool refresh = false;

            if (NavigationService.CanGoBack)
            {
                JournalEntry previous = NavigationService.BackStack.First();

                if (previous != null)
                {
                    if (previous.Source.ToString().Contains("VotePage"))
                    {
                        NavigationService.RemoveBackEntry();
                        refresh = true;
                    }
                }
            }

            if (refresh)
            {
                DataManager.Current.Clear<VotesModel>("votes");
            }

            this.DataContext = DataManager.Current.Load<VotesModel>(
                "votes",
                (vm) =>
                {
                    this.RefreshMap(vm);
                },
                (vm) =>
                {
                    this.FailedToRefreshMap();
                });
        }
        #endregion

        #region Private methods
        private static void UpdateLiveTileInformation(VotesModel vm)
        {
            if (vm != null)
            {
                // set new previousvotecount
                NorthernLights.PersistentVariables.Set<int>(Model.Enums.Variables.PreviousVoteCount.ToString(), vm.TotalVoteCount);

                // update live tile (set to 0)
                USElections.TileUpdates.ApplicationTile.Update(0);
            }
        }

        private void RefreshMap(VotesModel vm)
        {
            if (vm != null)
            {
                // clean map
                if (this.map != null)
                {
                    this.map.Children.Clear();
                }

                if (this.longlist != null && vm.States != null)
                {
                    this.longlist.ItemsSource = new StateDataByCode(vm.States);
                }

                if (vm.States != null)
                {
                    // set electoral votes chart.
                    BarSeries bs = this.chart.Series[0] as BarSeries;
                    bs.ShowLabels = true;
                    bs.ValueBinding = new GenericDataPointBinding<ChartElectoralObject, int>() { ValueSelector = obj => obj.Votes };
                    bs.CategoryBinding = new GenericDataPointBinding<ChartElectoralObject, string>() { ValueSelector = obj => obj.Party.ToString() + " Party" };
                    bs.ItemsSource = vm.States.TotalElectoralVoteCount().Where(x => x.Key != Candidate.Parties.Undecided).Select(x => new ChartElectoralObject() { Party = x.Key, Votes = x.Value });

                    // set popular votes chart.
                    BarSeries bs2 = this.chart2.Series[0] as BarSeries;
                    bs2.ShowLabels = true;
                    bs2.ValueBinding = new GenericDataPointBinding<ChartPopularObject, int>() { ValueSelector = obj => obj.Votes };
                    bs2.CategoryBinding = new GenericDataPointBinding<ChartPopularObject, string>() { ValueSelector = obj => obj.Candidate.FullName };
                    bs2.ItemsSource = vm.States.TotalPopularVoteCount().Select(x => new ChartPopularObject() { Candidate = x.Key, Votes = x.Value }).OrderByDescending(x => x.Votes);

                    // draw on map.
                    Renderer.DrawStates(this.map, vm.States);
                }

                UpdateLiveTileInformation(vm);
            }
            else
            {
                this.FailedToRefreshMap();
            }
        }

        private void FailedToRefreshMap()
        {
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                this.notification.Show("Failed to load/refresh data. Try again later.", new SolidColorBrush(Colors.Red), null);
            });
        }

        private void ApplicationBarIconButtonClick(object sender, EventArgs e)
        {
            ApplicationBarIconButton item = sender as ApplicationBarIconButton;

            if (item != null)
            {
                // refresh feed.
                if (string.Compare(item.Text, "refresh", StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    // refresh map data.
                    DataManager.Current.Refresh<VotesModel>(
                        "votes",
                        (vm) =>
                        {
                            this.RefreshMap(vm);
                        },
                        (vm) =>
                        {
                            this.FailedToRefreshMap();
                        });
                }

                if (string.Compare(item.Text, "center", StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    // center map.
                    this.map.SetView(new GeoCoordinate(54, -110), 2.1);
                }

                if (string.Compare(item.Text, "share", StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    var model = DataManager.Current.Load<VotesModel>("votes", (vm) => { }, (vm) => { });

                    // http://www.uselectionsapp.com url
                    string shortenedUrl = "http://bit.ly/xoFOJA";

                    ShareStatusTask sst = new ShareStatusTask();

                    string additional = string.Empty;

                    Candidate candidate = model.CandidateLeadingByElectoralVote;

                    if (candidate != null)
                    {
                        if (!string.IsNullOrEmpty(candidate.TwitterAccount))
                        {
                            additional = string.Format("@{1} is leading the race for the White House. ", model.TotalVoteCount, model.CandidateLeadingByElectoralVote.TwitterAccount);
                        }
                        else
                        {
                            additional = string.Format("{1} is leading the race for the White House. ", model.TotalVoteCount, model.CandidateLeadingByElectoralVote.FullName);
                        }
                    }

                    string info = string.Empty;

                    if (model != null)
                    {
                        info = string.Format("{0} people voted! {1}", model.TotalVoteCount, additional);
                    }

                    string status = string.Format("{0}(@uselectionsapp for Windows Phone {1} #wp)", info, shortenedUrl);

                    sst.Status = status;

                    if (sst.Status.Length > 140)
                    {
                        Debug.WriteLine("WARNING: Status too long for twitter!");
                    }

                    try
                    {
                        sst.Show();
                    }
                    catch
                    {
                    }
                }
            }
        }

        private void PivotSelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            Pivot pivot = sender as Pivot;

            if (pivot != null)
            {
                PivotItem item = pivot.SelectedItem as PivotItem;

                if (item != null)
                {
                    if (string.Compare(item.Header.ToString(), "overview", StringComparison.InvariantCultureIgnoreCase) == 0)
                    {
                        this.ApplicationBar.IsVisible = true;
                    }
                    else
                    {
                        this.ApplicationBar.IsVisible = false;
                    }
                }
            }
        }

        private void LongListSelector_GroupViewOpened(object sender, GroupViewOpenedEventArgs e)
        {
            Animations.LongListSelectorOpen(sender as LongListSelector, e);
        }

        private void LongListSelector_GroupViewClosing(object sender, GroupViewClosingEventArgs e)
        {
            Animations.LongListSelectorClosing(sender as LongListSelector, e);
        }
        #endregion
    }
}